package com.weimin.SportAppBackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.weimin.SportAppBackend.entity.User;
import com.weimin.SportAppBackend.mapper.UserMapper;
import jakarta.annotation.Resource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

/**
 * @author : huiMing
 * Date : 2025年06月25日 16:49
 * @version V1.0
 */

/**
 * Spring Security 用户详情服务实现
 * 负责从数据库加载用户认证信息
 */
@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Resource
    private UserMapper userMapper; // 注入用户 Mapper

    /**
     * 根据用户名 (这里可能是手机号或微信 OpenID) 加载用户详情
     * @param identifier 用户标识 (可能是手机号或微信 OpenID)
     * @return UserDetails 对象
     * @throws UsernameNotFoundException 如果用户未找到或账户状态异常
     */
    @Override
    public UserDetails loadUserByUsername(String identifier) throws UsernameNotFoundException {
        User user = null;

        // 尝试判断 identifier 是手机号还是 openid
        // 简单的判断逻辑：如果 identifier 是纯数字且长度为 11，则认为是手机号
        // 更严谨的判断可能需要正则表达式，或者根据业务规则进行区分
        if (identifier.matches("^1[3-9]\\d{9}$")) { // 简单的手机号正则判断
            LambdaQueryWrapper<User> phoneQueryWrapper = new LambdaQueryWrapper<>();
            phoneQueryWrapper.eq(User::getPhone, identifier);
            user = userMapper.selectOne(phoneQueryWrapper);
        }

        // 如果不是手机号，或者手机号查询不到，则尝试按 openid 查询
        if (user == null) {
            LambdaQueryWrapper<User> openidQueryWrapper = new LambdaQueryWrapper<>();
            openidQueryWrapper.eq(User::getOpenid, identifier);
            user = userMapper.selectOne(openidQueryWrapper);
        }

        // 如果用户不存在，则抛出 UsernameNotFoundException
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在或认证信息无效：" + identifier);
        }

        // 检查用户状态 (例如：0被禁用，1启用，2删除)
        // 假设 0 表示禁用，1 表示启用，其他值可能表示删除或其它状态
        if (user.getStatus() == null || user.getStatus() == 0) { // 0表示被禁用
            throw new UsernameNotFoundException("账户已被禁用，请联系管理员：" + identifier);
        }
        // 如果有其他状态，例如 2 表示已删除，可以继续添加判断
        // if (user.getStatus() == 2) {
        //     throw new UsernameNotFoundException("账户已删除，请联系管理员：" + identifier);
        // }


        // 返回 Spring Security 的 UserDetails 对象
        // 这里的密码是加密后的密码，Spring Security 会自动与用户输入的密码进行比对
        // 权限列表可以根据用户的 role 字段设置
        // 注意：org.springframework.security.core.userdetails.User 的第一个参数是“用户名”
        // 这个“用户名”需要与 JWT 的 subject 匹配，以便 validateToken 方法能够正确验证
        String usernameForUserDetails = user.getPhone() != null && !user.getPhone().isEmpty() ? user.getPhone() : user.getOpenid();

        // ⭐️ 关键修改：处理 user.getPassword() 可能为 null 的情况 ⭐️
        String userPassword = user.getPassword();
        if (userPassword == null) {
            userPassword = ""; // 如果密码为 null，则提供一个空字符串
            // 或者，如果您的安全策略要求，可以设置一个随机生成的、不会被用于实际验证的密码
            // userPassword = "{noop}dummy_password"; // {noop} 表示不进行密码编码
        }

        return new org.springframework.security.core.userdetails.User(
                usernameForUserDetails,     // 用户名 (这里是手机号或 OpenID，取决于哪个存在)
                userPassword,        // 加密后的密码 (可能为 null，对于微信登录但未设置密码的用户)
                user.getStatus() == 1,      // enabled (假设 1 为启用)
                true,                       // accountNonExpired
                true,                       // credentialsNonExpired (如果密码为空，这里可能需要特殊处理，但Spring Security通常允许空密码，如果您的认证提供者支持)
                true,                       // accountNonLocked
                new ArrayList<>()           // 权限列表，暂时为空，后续可根据角色添加
        );
    }
}
